/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.sonar.util.sync;

import bgu.sonar.util.ex.UncheckedInterruptedException;
import java.util.concurrent.Semaphore;
import org.openide.util.Exceptions;

/**
 * multi threaded singleton holder
 *
 * @author bennyl
 */
public abstract class MTSingleton<T> {

    private volatile T instance = null;
    private Semaphore creationLock = new Semaphore(1);

    public T get() {
        if (instance == null) {
            try {
                creationLock.acquire();
                if (instance == null) {
                    instance = construct();
                }
            } catch (InterruptedException ex) {
                throw new UncheckedInterruptedException(ex);
            } finally {
                creationLock.release();
            }
        }

        return instance;
    }

    protected abstract T construct();
}
